package io.gitee.chearnee.fw.openapi.business;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import io.gitee.chearnee.fw.openapi.business.entity.Application;
import io.gitee.chearnee.fw.openapi.business.entity.AuthorizedResources;
import io.gitee.chearnee.fw.openapi.business.entity.Company;
import io.gitee.chearnee.fw.openapi.business.service.ApplicationService;
import io.gitee.chearnee.fw.openapi.business.service.AuthorizedResourcesService;
import io.gitee.chearnee.fw.openapi.business.service.CompanyService;
import io.gitee.chearnee.fw.openapi.constant.enums.CommonStatusEnum;
import io.gitee.chearnee.fw.openapi.constant.enums.ContractStatusEnum;
import io.gitee.chearnee.fw.openapi.constant.enums.ResultCode;
import io.gitee.chearnee.fw.openapi.exception.OpenApiAsserts;
import io.gitee.chearnee.fw.web.entity.BaseEntity;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

/**
 * @author cn
 * @version 1.0
 * @description
 * @date 2021/9/23 16:44
 */
@Component
@AllArgsConstructor
public class BusinessManager {

  private final ApplicationService applicationService;
  private final AuthorizedResourcesService authorizedResourcesService;
  private final CompanyService companyService;
  private final CacheManager cacheManager;

  public void saveCompany(Company company) {
    companyService.save(company);
  }

  public void updateCompany(Company company) {
    companyService.updateById(company);
  }

  public void saveAuthorizedResources(AuthorizedResources authorizedResources) {
    authorizedResourcesService.save(authorizedResources);
  }

  public void updateResources(AuthorizedResources authorizedResources) {
    authorizedResourcesService.updateById(authorizedResources);
  }

  public void saveApplication(Application application) {
    applicationService.save(application);
  }

  public void updateApplication(Application application) {
    applicationService.update(application,
        Wrappers.<Application>lambdaUpdate().eq(Application::getAppId, application.getAppId()));
  }

  public List<Application> initApplications(List<Long> companyIds) {
    return applicationService.lambdaQuery()
        .eq(Application::getStatus, CommonStatusEnum.ENABLE)
        .in(!companyIds.isEmpty(), Application::getCompanyId, companyIds)
        .eq(Application::getDeleted, 0).list();
  }

  public void initCompanies(List<Long> ids) {
    List<Company> companyList = companyService.lambdaQuery()
            .select(Company::getId)
            .in(!ids.isEmpty(), BaseEntity::getId, ids)
            .eq(Company::getStatus, CommonStatusEnum.ENABLE)
            .eq(Company::getContractStatus, ContractStatusEnum.VALID_CONTRACT)
            .eq(Company::getDeleted, 0).list();
      List<Long> companyIds = companyList.stream().map(BaseEntity::getId).toList();
    if (!companyIds.isEmpty()) {
      List<Application> applications = initApplications(companyIds);
      // cacheManager.applicationsCache(applications);
    }
  }

  public Application getApplicationByAppid(String appid) {
      Optional<Application> applicationOpt = applicationService.lambdaQuery()
              .eq(Application::getAppId, appid)
              .eq(Application::getDeleted, 0).oneOpt();
      if (applicationOpt.isEmpty()) {
          OpenApiAsserts.error(ResultCode.NOT_FOUND);
      }
      Application application = applicationOpt.get();
      if (application.getStatus() != CommonStatusEnum.ENABLE) {
          OpenApiAsserts.error(ResultCode.FAILED, "当前appId被限制登陆");
      }
      return application;
  }

  public List<AuthorizedResources> listAuthorizedResources(String appid) {
    return authorizedResourcesService.lambdaQuery()
            .select(AuthorizedResources::getId, AuthorizedResources::getAppId,
                    AuthorizedResources::getBusinessId, AuthorizedResources::getResourcesType)
        .eq(AuthorizedResources::getAppId, appid)
        .eq(AuthorizedResources::getDeleted, 0).list();
  }

  public boolean updateApplicationTokenByAppId(String appId, String accessToken,
      LocalDateTime expiredTime) {
    return applicationService.lambdaUpdate().set(Application::getAccessToken, accessToken)
        .set(Application::getExpiresTime, expiredTime)
        .eq(Application::getAppId, appId).update();
  }
}
